import type { PluginItem } from '@babel/core'
import type { BabelPresetOptions, EnvironmentType } from './types'
import {
    resolveTargets,
    resolveModules,
    buildPresetEnvConfig,
    resolveJsxConfig,
    resolveReactVersion,
    shouldUseTransformRuntime
} from './utils'

/**
 * 多功能Babel预设库
 * 支持多种环境类型，自动适配最佳配置
 */
export default function preset(_: unknown, options: BabelPresetOptions = {}) {
    // 解构配置并设置默认值
    const {
        type = 'react',
        targets,
        modules,
        reactVersion,
        jsxImportSource,
        development = process.env.NODE_ENV === 'development',
        useTransformRuntime
    } = options

    // 解析环境类型和React版本
    const envType = type as EnvironmentType
    const resolvedReactVersion = resolveReactVersion(reactVersion)

    // 环境类型特征检测
    const isLib = envType.includes('lib')
    const isH5 = envType.includes('h5')
    const isTypeScript = envType.includes('-ts')
    const isReact = envType.includes('react') && !isH5
    const isPreact = envType.includes('preact') && !isH5

    // 解析目标环境和模块类型
    const resolvedTargets = resolveTargets(targets, envType, resolvedReactVersion)
    const resolvedModules = resolveModules(modules, envType)

    // 判断是否为现代ES模块
    const isModernEsModule = resolvedModules === false || resolvedModules === 'esm'

    // 构建插件列表
    const plugins: PluginItem[] = []

    // 1. 运行时优化插件 - 根据环境类型智能判断
    const useRuntime = shouldUseTransformRuntime(envType, resolvedModules, useTransformRuntime)
    if (useRuntime) {
        try {
            // 确保依赖存在
            require.resolve('@babel/plugin-transform-runtime')

            plugins.push([
                require('@babel/plugin-transform-runtime'),
                {
                    corejs: isLib ? 3 : false,
                    helpers: true,
                    regenerator: true,
                    useESModules: isModernEsModule,
                    // 库模式下指定绝对路径，确保正确解析
                    absoluteRuntime: isLib
                        ? require.resolve('@babel/runtime/package.json').replace(/package\.json$/, '')
                        : undefined
                }
            ])
        } catch (err) {
            throw new Error(
                `使用类型 ${envType} 需要安装 @babel/plugin-transform-runtime。\n` +
                `请运行: npm install --save-dev @babel/plugin-transform-runtime\n` +
                `${isLib ? '以及: npm install --save @babel/runtime-corejs3' : ''}`
            )
        }
    }

    // 2. 开发环境热更新插件 - 非lib模式且是React/Preact环境
    if (development && !isLib && (isReact || isPreact)) {
        try {
            if (isReact) {
                require.resolve('react-refresh/babel')
                plugins.push([require('react-refresh/babel'), { skipEnvCheck: true }])
            } else if (isPreact) {
                require.resolve('@prefresh/babel-plugin')
                plugins.push([require('@prefresh/babel-plugin')])
            }
        } catch (err) {
            // 热更新插件缺失时仅警告，不中断流程
            console.warn(`开发环境建议安装热更新插件: ${isReact ? 'react-refresh' : '@prefresh/babel-plugin'}`)
        }
    }

    // 构建预设列表
    const presets: PluginItem[] = []

    // 1. 核心预设（处理ES特性）
    presets.push([
        require('@babel/preset-env'),
        buildPresetEnvConfig(envType, resolvedTargets, resolvedModules)
    ])

    // 2. TypeScript预设（如果需要）
    if (isTypeScript) {
        try {
            require.resolve('@babel/preset-typescript')
            presets.push([require('@babel/preset-typescript')])
        } catch (err) {
            throw new Error(`使用TypeScript类型(${envType})需要安装@babel/preset-typescript`)
        }
    }

    // 3. JSX预设（如果需要）- H5环境不需要
    if (!isH5) {
        const jsxConfig = resolveJsxConfig(envType, jsxImportSource)
        if (jsxConfig) {
            try {
                require.resolve('@babel/preset-react')
                presets.push([require('@babel/preset-react'), jsxConfig])
            } catch (err) {
                throw new Error(`使用JSX环境(${envType})需要安装@babel/preset-react`)
            }
        }
    }

    return {
        sourceType: isModernEsModule ? 'module' : 'unambiguous',
        presets,
        plugins,
        overrides: [
            {
                test: /node_modules/,
                exclude: useRuntime ? [/@babel[/\\]runtime/, /core-js/] : [],
                sourceType: 'unambiguous'
            }
        ],
        assumptions: {
            setPublicClassFields: true,
            privateFieldsAsProperties: true,
            noDocumentAll: true
        }
    }
}
